package club.twelveblog.tblog.service;

import club.twelveblog.tblog.common.config.AliOssClient;
import club.twelveblog.tblog.common.config.GlobalConfig;
import club.twelveblog.tblog.common.constants.SessionConstants;
import club.twelveblog.tblog.common.enums.ExceptionEnum;
import club.twelveblog.tblog.common.exception.BlogException;
import club.twelveblog.tblog.dao.BlogInfoDao;
import club.twelveblog.tblog.dao.CategoryDao;
import club.twelveblog.tblog.dao.ResultRepository;
import club.twelveblog.tblog.dao.UserDao;
import club.twelveblog.tblog.entity.BlogInfo;
import club.twelveblog.tblog.entity.Category;
import club.twelveblog.tblog.entity.User;
import club.twelveblog.tblog.utils.DateUtils;
import club.twelveblog.tblog.utils.ReNameImage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Service
@Slf4j
public class BlogInfoService {
    @Autowired
    private BlogInfoDao blogInfoDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private ResultRepository resultRepository;


    private static final List<String> ALLOW_IMAGE_TYPE = Arrays.asList("image/jpeg", "image/jpg", "image/png", "image/gif");

    /**
     * 用户发表文章
     * @param blogInfo
     * @param category_id
     */
    public void saveBlogInfo(BlogInfo blogInfo,Long category_id) {
        List<BlogInfo> blogInfos = new ArrayList<>();
        blogInfo.setCreateTime(DateUtils.getLocalCurrentDate());
        blogInfo.setUpdateTime(DateUtils.getLocalCurrentDate());
        User user = userDao.getOne(SessionConstants.USER_ID);
        Category category = categoryDao.getOne(category_id);
        blogInfo.setUser(user);
        blogInfo.setCategory(category);
        int count = (int) blogInfoDao.count();
        int num = count + 1;
        blogInfo.setBlog_sub_url("http://localhost:8080/tblog/blogInfo/viewArticle/" + user.getUsername() + "/" + num);
        blogInfos.add(blogInfo);
        user.setBlogInfos(blogInfos);
        blogInfoDao.save(blogInfo);

    }

    /**
     * 博客文章图片上传
     *
     * @param file
     * @return
     */
    public String UploadBlogImg(MultipartFile file) {
        //用于存储图片访问路径
        String url = "";
        try {
            //校验文件类型
            String contentType = file.getContentType();
            if (!ALLOW_IMAGE_TYPE.contains(contentType)) {
                throw new BlogException(ExceptionEnum.INVALID_FILE_TYPE);
            }
            //校验文件内容
            BufferedImage image = ImageIO.read(file.getInputStream());
            if (image == null) {
                throw new BlogException(ExceptionEnum.INVALID_FILE_TYPE);
            }
            /// 创建新实例
            AliOssClient client = new AliOssClient();
            // 连接需要的信息
            client.setAccessKeyId(GlobalConfig.ACCESSKEYID);
            client.setAccessKeySecret(GlobalConfig.ACCESSKEYSECRET);
            client.setEndpoint(GlobalConfig.ENDPOINT);
            //调用重命名方法
            String fileName = ReNameImage.renameFile(file);
            // 获得文件流
            InputStream inputStream = file.getInputStream();
            //上传到OSS
            client.putObject(GlobalConfig.BUCKETNAME, "blogImg/" + fileName, inputStream);
            System.out.println("图片下载url是:" + url);
            url += "https://tblog.oss-cn-beijing.aliyuncs.com/blogImg/" + fileName;
            return url;
        } catch (IOException e) {
            //上传失败
            log.error("上传图片失败", e);
            throw new BlogException(ExceptionEnum.UPLOADIMAGE_ERROR);
        }
    }

    /**
     * 查询指定用户下的所有已发布的文章
     *
     * @param page
     * @return
     */
    public Page<List<BlogInfo>> findMyBlogInfo(int page) {

        //根据创建时间的先后排序
        PageRequest pageRequest = PageRequest.of(page - 1, 3, new Sort(Sort.Direction.DESC, "create_time"));
        Page<List<BlogInfo>> myBlogInfo = blogInfoDao.findMyBlogInfo(SessionConstants.USER_ID, pageRequest);
        return myBlogInfo;
    }

    /**
     * 查看博客文章
     *
     * @param blogId
     * @return
     */
    public BlogInfo viewArticle(Long blogId) {
        int i=0;
        BlogInfo blogInfo = blogInfoDao.getOne(blogId);
        blogInfo.setBlog_views(i++);
        Optional<BlogInfo> info = blogInfoDao.findById(blogId);
        return info.get();
    }

    /**
     * 更新博客文章
     *
     * @param blogInfo
     */
    public void updateArticle(BlogInfo blogInfo) {
        try {
            BlogInfo info = blogInfoDao.getOne(blogInfo.getBlog_id());
            info.setBlog_title(blogInfo.getBlog_title());
            info.setBlog_preface(blogInfo.getBlog_preface());
            info.setBlog_content(blogInfo.getBlog_content());
            info.setBlog_status(blogInfo.getBlog_status());
            info.setUpdateTime(DateUtils.getLocalCurrentDate());
            blogInfoDao.save(info);
        } catch (BlogException e) {
            throw new BlogException(ExceptionEnum.UPDATE_FAILED);
        }
    }

    /**
     * 禁止、允许评论
     *
     * @param blogInfo
     * @return
     */
    public void banComment(BlogInfo blogInfo) {

        BlogInfo info = blogInfoDao.getOne(blogInfo.getBlog_id());
        info.setEnable_comment(blogInfo.getEnable_comment());
        blogInfoDao.save(info);
    }

    /**
     * 删除文章，将文章状态更改为1，1为删除
     *
     * @param blogId
     */
    public void deleteArticle(Long blogId) {
        BlogInfo info = blogInfoDao.getOne(blogId);
        info.setIs_deleted(1);
        blogInfoDao.save(info);
    }

    /**
     * 查找未删除的所有文章
     * @return
     */
    public Page<List<BlogInfo>> queryBlogsNoDel() {
        PageRequest pageRequest = PageRequest.of(0, 3, new Sort(Sort.Direction.DESC, "createTime"));
        Page<List<BlogInfo>> listPage = blogInfoDao.queryBlogsNoDel(pageRequest);
        return listPage;
    }

    /**
     * 根据分类名称查找对应博客文章
     * @param categoryName
     * @return
     */
    public Page<List<BlogInfo>> findBlogInfoByCategoryName(String categoryName) {
        Category category = categoryDao.findByCategoryName(categoryName);
        PageRequest pageRequest = PageRequest.of(0, 3, new Sort(Sort.Direction.DESC, "create_time"));
        Page<List<BlogInfo>> infoByCid = blogInfoDao.findBlogInfoByCid(category.getCategory_id(),pageRequest);
        return infoByCid;
    }
}
